import json
from typing import Dict, Any, List

from fastapi import FastAPI


async def parse_openapi_docs(app: FastAPI):
    """
    解析 openapi.json 文件，以获取所有 api 接口，并将其保存至 'static/init_data/api.json'
    :param app: FastAPI
    :return:
    """
    # 1、获得api文档
    docs: Dict[str, Any] = app.openapi()

    # 2、遍历所有tags, 生成模块数据
    tags: List[Dict[str, Any]] = docs["tags"]
    # 以第一个 tags 的名称为键，确认 action 和 module 父子关系
    modules: Dict[str, Dict[str, Any]] = {}
    for index, tag in enumerate(tags):
        model_info = {
            "name": tag["name"],
            "label": tag["description"],
            "path": tag["name"],
            "sort": index + 1,
            "is_enabled": True
        }
        modules[tag["name"]] = model_info

    # 3、获得所有 paths, 生成action数据
    paths: Dict[str, Any] = docs["paths"]
    # 以第一个 tags 的名称为键，确认 action 和 module 父子关系
    actions: Dict[str, List[Dict[str, Any]]] = {}
    sort = 1
    current_tage = ""
    for key, value in paths.items():
        path = key.split("/{")[0]
        for k, v in value.items():
            http_method = k
            name = v["operationId"].split("_api_")[0]
            label = v["summary"]
            tag = v["tags"][0]
            # 如果 current_tag 不等于tag， 则进入下一个路由模块，重置 sort 为 1
            if current_tage != tag:
                sort = 1
            path_info = {
                "name": name,
                "label": label,
                "path": path,
                "http_method": http_method,
                "sort": sort,
                "is_enabled": True,
                "tag": tag,
            }
            # 添加前先检查标签是否存在
            if tag not in actions:
                actions[tag] = []
            actions[tag].append(path_info)
            current_tage = tag
            # 只获取第一个 action 的数据
            break
        sort += 1

    # 4、变量所有模块，找到对应的 action
    apis: List[Dict[str, Any]] = []
    for key, value in modules.items():
        value["children"] = actions[key]
        apis.append(value)


    # 将 api 接口保存至本地，用于 api 接口同步
    # 如果想要好看，使用 indent=4 控制缩进，但是文件大小会变大
    with open("static/init_data/api.json", "w", encoding="utf-8") as file:
        json.dump(apis, file, ensure_ascii=False, indent=4)

    # with open("static/init_data/openapi.json", "w", encoding="utf-8") as file:
    #    json.dump(docs, file, ensure_ascii=False, indent=4)
